import sys
import os
from datetime import datetime, timedelta
import argparse
import pandas as pd
import numpy as np
import json
import ccxt
from typing import Dict, List

from config.settings import (
    EXCHANGE_CONFIG,
    BACKTEST_CONFIG,
    TRADING_CONFIG,
    ML_CONFIG,
    DATA_CONFIG,
    RiskConfig
)
from data import HistoricalDataHandler, LiveDataHandler
from strategies import MLEnhancedStrategy
from analysis import MarketAnalyzer, ChainAnalyzer, SentimentAnalyzer, TechnicalIndicators
from analysis import MLPredictor
from risk import RiskManager
from backtest import BacktestEngine
from utils import visualization

def prepare_ml_model(data_handler: HistoricalDataHandler, exchange: str, symbol: str) -> MLPredictor:
    """准备和训练机器学习模型"""
    print("准备市场数据...")
    
    try:
        # 获取历史数据
        data = data_handler.get_all_bars()
        
        # 检查数据是否存在
        print(f"检查数据可用性...")
        print(f"可用的交易所: {list(data.keys())}")
        print(f"当前交易所: {exchange}")
        
        if exchange not in data:
            print(f"错误: 找不到交易所 {exchange} 的数据")
            print(f"可用的交易所: {list(data.keys())}")
            raise KeyError(f"交易所 {exchange} 不存在")
            
        if symbol not in data[exchange]:
            print(f"错误: 找不到交易对 {symbol} 的数据")
            print(f"可用的交易对: {list(data[exchange].keys())}")
            raise KeyError(f"交易对 {symbol} 不存在")
        
        # 获取历史数据
        df = data[exchange][symbol].copy()
        
        print(f"获取到 {len(df)} 条数据")
        print("数据示例:")
        print(df.head())
        
        # 计算技术指标
        ti = TechnicalIndicators()
        print("\n计算技术指标...")
        df = ti.calculate_all(df)
        
        # 计算自定义特征
        print("\n计算自定义特征...")
        df = ti.calculate_custom_features(df)
        
        # 训练模型
        print("\n训练机器学习模型...")
        ml_predictor = MLPredictor()
        results = ml_predictor.train_models(df)
        print("ML模型训练结果:", results)
        
        return ml_predictor
        
    except Exception as e:
        print(f"\n准备ML模型时出错: {str(e)}")
        raise

def run_backtest(config: Dict, start_date: str, end_date: str):
    """运行回测"""
    print("\n=== 加密货币交易机器人回测系统 ===")
    print(f"交易所: {config['exchange']}")
    print(f"交易对: {config['symbols'][0]}")
    print(f"时间周期: {DATA_CONFIG['timeframe']}")
    print(f"初始资金: ${BACKTEST_CONFIG['initial_capital']:,.2f}")
    print(f"回测期间: {start_date} 到 {end_date}")
    
    try:
        print(f"Starting backtest from {start_date} to {end_date}\n")
        
        # 初始化交易所
        exchange_class = getattr(ccxt, config['exchange'])
        exchange_config = EXCHANGE_CONFIG[config['exchange']].copy()
        exchange = exchange_class(exchange_config)
        
        # 初始化数据处理器
        exchanges = {config['exchange']: exchange}
        data_handler = HistoricalDataHandler(
            exchanges=exchanges,
            symbols=config['symbols'],
            timeframe=DATA_CONFIG['timeframe'],
            start_date=datetime.strptime(start_date, '%Y-%m-%d'),
            end_date=datetime.strptime(end_date, '%Y-%m-%d')
        )
        
        # 准备ML模型
        ml_predictor = prepare_ml_model(
            data_handler,
            config['exchange'],
            config['symbols'][0]
        )
        
        # 初始化技术指标分析器
        technical_indicators = TechnicalIndicators()
        
        # 初始化市场分析器
        market_analyzer = MarketAnalyzer(
            technical_indicators=technical_indicators,
            ml_predictor=ml_predictor
        )
        
        # 创建风险管理配置
        risk_config = RiskConfig(
            initial_capital=BACKTEST_CONFIG['initial_capital'],
            max_position_size=TRADING_CONFIG['position_size'],
            stop_loss=TRADING_CONFIG['stop_loss'],
            take_profit=TRADING_CONFIG['take_profit']
        )
        
        # 初始化风险管理器
        risk_manager = RiskManager(config=risk_config)
        
        # 初始化策略
        strategy = MLEnhancedStrategy(
            market_analyzer=market_analyzer,
            risk_manager=risk_manager,
            technical_indicators=technical_indicators,
            ml_predictor=ml_predictor
        )
        
        # 初始化回测引擎
        backtest = BacktestEngine(
            data_handler=data_handler,
            strategy=strategy,
            risk_manager=risk_manager,
            initial_capital=BACKTEST_CONFIG['initial_capital']
        )
        
        # 运行回测
        results = backtest.run_backtest()
        
        # 保存回测结果
        save_backtest_results(results, config)
        
        # 显示回测结果
        print("\n=== 回测结果 ===")
        print(f"总收益: {results['total_return']:.2%}")
        print(f"最大回撤: {results['max_drawdown']:.2%}")
        print(f"夏普比率: {results['sharpe_ratio']:.2f}")
        print(f"交易次数: {results['total_trades']}")
        print(f"胜率: {results['win_rate']:.2%}")
        
        # 绘制回测结果
        visualization.plot_trading_results(results)
        visualization.plot_trade_analysis(results)
        
    except Exception as e:
        print(f"\n错误: {str(e)}")
        raise

def optimize_strategy(
    start_date: datetime,
    end_date: datetime,
    symbol: str = 'BTC/USDT',
    timeframe: str = '1h'
):
    """优化策略参数"""
    print("\n=== 策略优化 ===")
    print(f"交易对: {symbol}")
    print(f"优化期间: {start_date} 到 {end_date}")
    
    # 这里添加参数优化的代码
    pass

def save_backtest_results(results: Dict, config: Dict):
    """保存回测结果"""
    # 创建结果目录
    results_dir = os.path.join(os.getcwd(), 'results')
    os.makedirs(results_dir, exist_ok=True)
    
    # 生成结果文件名
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    filename = f"backtest_results_{config['exchange']}_{config['symbols'][0]}_{timestamp}.json"
    filepath = os.path.join(results_dir, filename)
    
    # 保存结果
    with open(filepath, 'w') as f:
        json.dump(results, f, indent=4)
    
    print(f"\n回测结果已保存到: {filepath}")

def main():
    """主程序入口"""
    parser = argparse.ArgumentParser(description='加密货币交易机器人')
    parser.add_argument('--mode', choices=['backtest', 'optimize', 'live'],
                      default='backtest', help='运行模式')
    parser.add_argument('--exchange', default='okx', help='交易所')
    parser.add_argument('--symbol', default='BTC/USDT', help='交易对')
    parser.add_argument('--start', default='2023-01-01', help='开始日期')
    parser.add_argument('--end', default='2023-12-31', help='结束日期')
    
    args = parser.parse_args()
    
    config = {
        'exchange': args.exchange,
        'symbols': [args.symbol]
    }
    
    if args.mode == 'backtest':
        results = run_backtest(config, args.start, args.end)
    elif args.mode == 'optimize':
        optimize_strategy(
            start_date=datetime.strptime(args.start, '%Y-%m-%d'),
            end_date=datetime.strptime(args.end, '%Y-%m-%d'),
            symbol=args.symbol
        )
    else:
        print("实时交易模式尚未实现")

if __name__ == "__main__":
    main()